package cn.yunyichina.provider.pay.service.impl;

import cn.yunyichina.provider.framework.dubbo.service.WechatPayService;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.ResponseObject;
import cn.yunyichina.provider.iface.entity.pay.BillDownloadRequest;
import cn.yunyichina.provider.iface.entity.pay.PayCode;
import cn.yunyichina.provider.iface.entity.pay.WechatMedicalBillDownloadRequest;
import cn.yunyichina.provider.iface.entity.pay.WechatMedicalBillDownloadResponse;
import cn.yunyichina.provider.pay.constant.ResponseEnum;
import cn.yunyichina.provider.pay.entity.PaymentSetting;
import cn.yunyichina.provider.pay.exception.PaySettingNotFoundException;
import cn.yunyichina.provider.pay.service.BaseBillService;
import cn.yunyichina.provider.pay.service.BillService;
import cn.yunyichina.utils.convert.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.validation.Validator;
import java.util.List;

/**
 * 下载对账单
 * Created by Lullaby on 2017/9/27
 */
@Service
public class BillServiceImpl extends BaseBillService implements BillService {

    private static final Logger logger = LoggerFactory.getLogger(BillServiceImpl.class);

    @Resource
    private Validator validator;

    /**
     * 下载对账单接口
     *
     * @param json
     * @return
     */
    public ResponseObject downloadBill(String json) {
        logger.info("BillServiceImpl.downloadBill.json -> {}", json);

        try {
            BillDownloadRequest request = JsonUtils.parseObject(json, BillDownloadRequest.class);
            List<String> messages = getValidationMessage(validator.validate(request));
            if (!CollectionUtils.isEmpty(messages)) {
                return new ResponseObject().buildResultCodeAndMessageAndResult(
                        ResponseEnum.Common.INVALID.getCode(), ResponseEnum.Common.INVALID.getMessage(), messages);
            }

            String payCode = request.getPayCode();
            switch (PayCode.valueOf(payCode)) {
                case WECHAT:
                    return downloadWechatBill(request);
                case WECHATMEDICAL:
                    return downloadWechatMedicalBill(request);
                case ALIPAY:
                    return downloadAlipayBill(request);
                case PACITY:
                    return downloadPacityBill(request);
                default:
                    return new ResponseObject().buildResultCodeAndMessage(
                            ResponseEnum.UNSUPPORTED.getCode(),
                            ResponseEnum.UNSUPPORTED.getMessage()
                    );
            }
        } catch (PaySettingNotFoundException e) {
            logger.error("BillServiceImpl.downloadBill.PaySettingNotFoundException", e);
            return new ResponseObject().buildResultCodeAndMessage(
                    ResponseEnum.PAY_SETTING_NOT_FOUND.getCode(),
                    ResponseEnum.PAY_SETTING_NOT_FOUND.getMessage()
            );
        } catch (Exception e) {
            logger.error("BillServiceImpl.downloadBill.Exception", e);
            return new ResponseObject().buildResultCodeAndMessage(
                    ResponseEnum.DOWNLOAD_BILL_EXCEPTION.getCode(),
                    ResponseEnum.DOWNLOAD_BILL_EXCEPTION.getMessage()
            );
        }
    }

    /**
     * 下载微信支付对账单
     *
     * @param request
     * @return
     */
    private ResponseObject downloadWechatBill(BillDownloadRequest request) {
        return null;
    }

    /**
     * 下载微信医疗支付对账单
     *
     * @param request
     * @return
     * @throws PaySettingNotFoundException
     */
    private ResponseObject downloadWechatMedicalBill(BillDownloadRequest request) throws PaySettingNotFoundException {
        String appid = request.getAppId();
        String orgCode = request.getHospitalCode();

        PaymentSetting parentSetting = this.getPaymentSetting(appid);
        if (parentSetting == null) throw new PaySettingNotFoundException("ParentSetting not found");
        logger.info("BillServiceImpl.downloadWechatMedicalBill.parentSetting -> {}", JsonUtils.toJsonString(parentSetting));

        PaymentSetting subSetting = this.getSubPaymentSettingByParentIdAndOrgCodeAndPayMode(parentSetting.getId(), orgCode, PayCode.WXMEDICALPAY.getMode());
        if (subSetting == null) throw new PaySettingNotFoundException("SubSetting not found");
        logger.info("BillServiceImpl.downloadWechatMedicalBill.subSetting -> {}", JsonUtils.toJsonString(subSetting));

        String apiSecret = parentSetting.getMedicarePayKey();

        String accessToken = getWechatMedicalPayAccessToken(
                buildMedicalPayAccessTokenParametersMap(
                        subSetting.getPayAppId(),
                        parentSetting.getPayAppId(),
                        parentSetting.getSecretKey()
                )
        );
        logger.info("BillServiceImpl.downloadWechatMedicalBill.accessToken -> {}", accessToken);

        if (StringUtils.isEmpty(accessToken))
            return new ResponseObject().buildResultCodeAndMessage(
                    ResponseEnum.WECHAT_ACCESS_TOKEN_FAILURE.getCode(),
                    ResponseEnum.WECHAT_ACCESS_TOKEN_FAILURE.getMessage()
            );

        WechatMedicalBillDownloadRequest billRequest = new WechatMedicalBillDownloadRequest();
        billRequest.setAppid(parentSetting.getPayAppId());
        billRequest.setMchId(parentSetting.getMerchantAccount());
        billRequest.setSubAppid(subSetting.getPayAppId());
        billRequest.setSubMchId(subSetting.getMerchantAccount());
        billRequest.setBillDate(request.getBillDate());
        billRequest.setBillType(request.getBillType());
        billRequest.setApiSecret(apiSecret);
        billRequest.setAccessToken(accessToken);
        logger.info("BillServiceImpl.downloadWechatMedicalBill.billRequest -> {}", JsonUtils.toJsonString(billRequest));

        ResCommon<WechatMedicalBillDownloadResponse> billResponse = WechatPayService.getWechatPayClient().downloadWechatMedicalBill(billRequest);
        logger.info("BillServiceImpl.downloadWechatMedicalBill.billResponse -> {}", JsonUtils.toJsonString(billResponse));

        if (!billResponse.isSuccess())
            return new ResponseObject().buildResultCodeAndMessageAndResult(
                    ResponseEnum.PAY_FAILURE.getCode(),
                    ResponseEnum.PAY_FAILURE.getMessage(),
                    billResponse.getResult()
            );

        return new ResponseObject().buildResultCodeAndMessageAndResult(
                billResponse.getResultCode(),
                billResponse.getResultMessage(),
                billResponse.getResult()
        );
    }

    /**
     * 下载支付宝支付对账单
     *
     * @param request
     * @return
     */
    private ResponseObject downloadAlipayBill(BillDownloadRequest request) {
        return null;
    }

    /**
     * 下载平安付对账单
     *
     * @param request
     * @return
     */
    private ResponseObject downloadPacityBill(BillDownloadRequest request) {
        return null;
    }

}
